package cn.sh.yhk.config;

import cn.sh.yhk.utils.SpringUtils;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.core.strategy.keygen.SnowflakeShardingKeyGenerator;
import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.*;
import java.util.Collection;

@Component
public class StandardPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    private final Integer TBALE_MAX_ROWS = 10;
    private final String SHARDING_DATASOURCE_KEY = "yhk";


    @Override
    @ShardingTransactionType
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
//        SqlMapper sqlMapper = (SqlMapper) SpringUtils.getObject(SqlMapper.class);
//        availableTargetNames.forEach(name -> {
//            try {
//                Long maxRow = getTableCount(SHARDING_DATASOURCE_KEY, name);
//            } catch (SQLException throwables) {
//                throwables.printStackTrace();
//            }
//        });

//        //shardingValue.getValue()
//        TUserExample.Criteria criteria = example.createCriteria();
//        criteria.andIdEqualTo(shardingValue.getValue());
//        Integer idSize = tUserMapper.selectByExample(example).get(0).getUserId();
//        if (idSize <= TBALE_MAX_ROWS) {
//
//        } else {
//
//        }
        return null;

    }


    /**
     * 保留空余的表 默认2张表
     *
     * @param DataSourceName
     */
    void allowanceTable(String DataSourceName,int allowanceNum,Collection<String> availableTargetNames) throws SQLException {
        DataSource dataSource = (DataSource) SpringUtils.getObject(DataSource.class);
        Connection connection = ((ShardingDataSource) dataSource).getDataSourceMap().get(SHARDING_DATASOURCE_KEY).getConnection();
        availableTargetNames.forEach(name -> {

        });


    }


    /**
     * SELECT table_name FROM information_schema.TABLES WHERE table_name =''" + tableName + "'';
     * 获取行数
     *
     * @param DataSourceName
     * @param tableName
     * @return
     * @throws SQLException
     */
    Long exisitTable(String DataSourceName, String tableName) throws SQLException {
        DataSource dataSource = (DataSource) SpringUtils.getObject(DataSource.class);
        Connection connection = ((ShardingDataSource) dataSource).getDataSourceMap().get(SHARDING_DATASOURCE_KEY).getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement("SELECT table_name FROM information_schema.TABLES WHERE table_name =''\" + tableName + \"''");
        ResultSet rs = preparedStatement.executeQuery();
        if (rs.next()) {
            return rs.getLong(1);
        } else {
            return null;
        }
    }

    /**
     * SELECT table_name FROM information_schema.TABLES WHERE table_name ='表名';
     * 获取行数
     *
     * @param DataSourceName
     * @param tableName
     * @return
     * @throws SQLException
     */
    Long getTableCount(String DataSourceName, String tableName) throws SQLException {
        DataSource dataSource = (DataSource) SpringUtils.getObject(DataSource.class);
        Connection connection = ((ShardingDataSource) dataSource).getDataSourceMap().get(SHARDING_DATASOURCE_KEY).getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement("select count(1) from " + tableName);
        ResultSet rs = preparedStatement.executeQuery();
        if (rs.next()) {
            return rs.getLong(1);
        } else {
            return null;
        }
    }

    /**
     * @param DataSourceName
     * @param tableName
     * @return
     * @throws SQLException
     */
    boolean createTable(String DataSourceName, String tableName) throws SQLException {
        DataSource dataSource = (DataSource) SpringUtils.getObject(DataSource.class);
        Connection connection = ((ShardingDataSource) dataSource).getDataSourceMap().get(SHARDING_DATASOURCE_KEY).getConnection();
        Statement stmt = connection.createStatement();
        boolean flag = stmt.execute("create table" + tableName +
                "( id bigint not null comment '分布ID' primary key, " +
                "user_id int auto_increment comment '自增ID', " +
                "name varchar(64) null comment '名称', " +
                "city_id int(12) null comment '城市', " +
                "sex tinyint(1) null comment '性别', " +
                "phone varchar(32) null comment '电话', " +
                "email varchar(32) null comment '邮箱', " +
                "create_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '创建时间', " +
                "password varchar(32) null comment '密码', " +
                "constraint id unique (user_id) )");
        connection.close();
        return flag;
    }

    public static Comparable<?> getId(Long workerId) {
        if (!(workerId >= 0 && workerId < 1024L)) {
            throw new RuntimeException(String.format("workerId is not support range must be [0,1024)"));
        }
        SnowflakeShardingKeyGenerator snowflakeShardingKeyGenerator = new SnowflakeShardingKeyGenerator();
        snowflakeShardingKeyGenerator.getProperties().put("worker.id", String.valueOf(workerId));
        Comparable<?> generateKey = snowflakeShardingKeyGenerator.generateKey();
        return generateKey;
    }


}
